package com.jcn.seckill.service;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jcn.seckill.dao.MiaoshaUserDao;
import com.jcn.seckill.domain.MiaoshaUser;
import com.jcn.seckill.exception.GlobalException;
import com.jcn.seckill.redis.MiaoshaUserKey;
import com.jcn.seckill.redis.RedisService;
import com.jcn.seckill.result.CodeMsg;
import com.jcn.seckill.util.MD5Util;
import com.jcn.seckill.util.UUIDUtil;
import com.jcn.seckill.vo.LoginVo;

//将自动注册到Spring容器，不需要再在applicationContext.xml文件定义bean了
@Service
public class MiaoshaUserService {
	
	//状态编码
	public static final String COOKI_NAME_TOKEN = "token";
	
	//对类成员变量、方法及构造函数进行标注，完成自动装配的工作
	//@Autowired标注可以放在成员变量上，也可以放在成员变量的set方法上，也可以放在任意方法上表示
	@Autowired
	//注入接口
	MiaoshaUserDao miaoshaUserDao;
	
	//对类成员变量、方法及构造函数进行标注，完成自动装配的工作
	//@Autowired标注可以放在成员变量上，也可以放在成员变量的set方法上，也可以放在任意方法上表示
	@Autowired
	//注入接口
	RedisService redisService;
	//public最好做参数校验
	//对象缓存
	public MiaoshaUser getById(long id) {
		//1.取缓存，通过id来获取对象
		//对象缓存希望是永久有效的，所以不设置有效期
		//key:id
		MiaoshaUser user = redisService.get(MiaoshaUserKey.getById, ""+id, MiaoshaUser.class);
		if(user != null) {
			return user;
		}
		//2.取数据库
		user = miaoshaUserDao.getById(id);
		if(user != null) {//如果获取的对象不为空
			//将对象写入redis中
			redisService.set(MiaoshaUserKey.getById, ""+id, user);
		}
		return user;
	}
	// http://blog.csdn.net/tTU1EvLDeLFq5btqiK/article/details/78693323
	//修改密码
	public boolean updatePassword(String token, long id, String formPass) {
		//1.取user对象
		MiaoshaUser user = getById(id);
		if(user == null) {
			throw new GlobalException(CodeMsg.MOBILE_NOT_EXIST);
		}
		//更新数据库
		//创建新对象：更新的对象越多，产生的sql与log就越多，为了提高效率，修改哪个字段，就更新哪个字段。
		MiaoshaUser toBeUpdate = new MiaoshaUser();
		toBeUpdate.setId(id);
		toBeUpdate.setPassword(MD5Util.formPassToDBPass(formPass, user.getSalt()));
		miaoshaUserDao.update(toBeUpdate);
		//对象缓存的特点
		//处理缓存，防止缓存不一致
		//数据更新成功之后，需要对缓存进行删除或者修改，跟MiaoshaUser的id有关的缓存
		//删除
		redisService.delete(MiaoshaUserKey.getById, ""+id);
		//更新密码
		user.setPassword(toBeUpdate.getPassword());
		//不能对token进行删除，删除后用户没法登录，所以进行更新
		redisService.set(MiaoshaUserKey.token, token, user);
		return true;
	}


	public MiaoshaUser getByToken(HttpServletResponse response, String token) {
		//public方法要养成第一步就进行参数校验的好习惯
		if(StringUtils.isEmpty(token)) {
			return null;
		}
		//对象缓存：根据token来获取对象，粒度最小
		MiaoshaUser user = redisService.get(MiaoshaUserKey.token, token, MiaoshaUser.class);
		//延长有效期：重新生成cookie
		if(user != null) {
			addCookie(response, token, user);
		}
		return user;
	}
	

	public String login(HttpServletResponse response, LoginVo loginVo) {
		if(loginVo == null) {
			throw new GlobalException(CodeMsg.SERVER_ERROR);
		}
		//获取手机号与密码：在form中通过一次的加密的密码
		String mobile = loginVo.getMobile();
		String formPass = loginVo.getPassword();
		System.out.println("【formPass:】" + formPass + "******************");
		//获取用户手机号
		MiaoshaUser user = getById(Long.parseLong(mobile));
		//判断手机号是否存在
		if(user == null) {
			throw new GlobalException(CodeMsg.MOBILE_NOT_EXIST);
		}
		//验证密码
		//二次MD5：获取dbPass、saltDB
		String dbPass = user.getPassword();
		System.out.println("【dbPass：】" + dbPass + "*****************");
		//String saltDB = user.getSalt();
		String saltDB = "1a2b3c4d";
		System.out.println("【saltDB：】" + saltDB + "*******************");
		//获取加密后的密码
		String calcPass = MD5Util.formPassToDBPass(formPass, saltDB);
		System.out.println("【calcPass：】" + calcPass + "*****************");
		//与dbpass比较
		if(!calcPass.equals(dbPass)) {
			throw new GlobalException(CodeMsg.PASSWORD_ERROR);
		}
		//生成cookie
		//查看token对应哪个用户，需要将用户信息写入redis中
		String token = UUIDUtil.uuid();
		//从缓存中重新设置该值，生成新的cookie
		addCookie(response, token, user);
		return token;
	}
	
	private void addCookie(HttpServletResponse response, String token, MiaoshaUser user) {
		//将用户信息存入redis中
		//user:用户信息，以后拿到token就能知道用户信息
		redisService.set(MiaoshaUserKey.token, token, user);
		//生成cookie
		Cookie cookie = new Cookie(COOKI_NAME_TOKEN, token);
		//设置cookie有效期与session保持一致（MiaoshaUserKey.token）
		cookie.setMaxAge(MiaoshaUserKey.token.expireSeconds());
		//设置网站根目录
		cookie.setPath("/");
		//生成完后写入到response里面，将cookie写入客户端
		response.addCookie(cookie);
	}

}
